package com.zdl.interestingapp.utils

import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import org.jetbrains.annotations.NotNull

/**
 * @author zdl
 * @date 2018/4/25 11:35
 * email zdl328465042@163.com
 * description 封装图片相关的工具
 */
object MyImageUtil {

    /**
     * 从SD卡中加载图片
     * @param pathName pathName
     * @param reqWidth reqWidth
     * @param reqHeight reqHeight
     * @return Bitmap
     */
    fun getBitmapFromSd(@NotNull pathName: String, @NotNull reqWidth: Int, @NotNull reqHeight: Int): Bitmap {
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        BitmapFactory.decodeFile(pathName, options)
        options.inSampleSize = computeInSampleSize(options, reqWidth, reqHeight)
        options.inJustDecodeBounds = false
        val src = BitmapFactory.decodeFile(pathName, options)
        return createScaleBitmap(src, reqWidth, reqHeight)
    }

    /**
     * 从Resources中加载图片
     * @param res Resources
     * @param id id
     * @param reqWidth reqWidth
     * @param reqHeight reqHeight
     * @return Bitmap
     */
    fun getBitmapFromResources(@NotNull res: Resources, @NotNull id: Int, @NotNull reqWidth: Int, @NotNull reqHeight: Int): Bitmap {
        //首先通过 options.inJustDecodeBounds = true 获得图片的尺寸
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        BitmapFactory.decodeResource(res, id, options)
        //然后根据图片分辨率以及我们实际需要展示的大小，计算压缩率
        options.inSampleSize = computeInSampleSize(options, reqWidth, reqHeight)
        //设置压缩率，并解码
        options.inJustDecodeBounds = false
        val src = BitmapFactory.decodeResource(res, id, options)
        //返回目标大小的缩略图
        return createScaleBitmap(src, reqWidth, reqHeight)
    }

    /**
     * 根据图片分辨率以及我们实际需要展示的大小，计算压缩率
     * @param options BitmapFactory.Options
     * @param reqWidth reqWidth
     * @param reqHeight reqHeight
     * @return int
     */
    private fun computeInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
        val width = options.outWidth
        val height = options.outHeight
        var inSampleSize = 1
        if (height > reqHeight || width > reqWidth) {
            val halfHeight = height / 2
            val halfWidth = width / 2
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2
            }
        }
        return inSampleSize
    }

    /**
     * 如果是放大图片，filter决定是否平滑，如果是缩小图片，filter无影响
     * @param src Bitmap
     * @param dstWidth dstWidth
     * @param dstHeight dstHeight
     * @return Bitmap
     */
    private fun createScaleBitmap(src: Bitmap, dstWidth: Int, dstHeight: Int): Bitmap {
        val dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false)
        //如果没有缩放，那么不回收
        if (src != dst) {
            //释放Bitmap的native像素数组
            src.recycle()
        }
        return dst
    }

    /**
     * Drawable 转 Bitmap
     * @param drawable 源drawable
     * @return bitmap
     */
    fun drawable2bitmap(@NotNull drawable: Drawable): Bitmap {
        if (drawable is BitmapDrawable) {
            return drawable.bitmap
        }
        val width = drawable.intrinsicWidth
        val height = drawable.intrinsicHeight
        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, width, height)
        drawable.draw(canvas)
        return bitmap
    }

    /**
     * Bitmap 转 Drawable
     * @param bitmap bitmap
     * @return drawable
     */
    fun bitmap2drawable(@NotNull res: Resources, @NotNull bitmap: Bitmap): Drawable {
        return BitmapDrawable(res, bitmap)
    }
}